package com.simon.webflux.controller;

import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import som.simon.reactor.SimonUtil;
import som.simon.reactor.error.BusinessException;

import java.time.Duration;
import java.util.UUID;

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping("/msg")
    public String getMsg() {
        return UUID.randomUUID().toString();
    }

    @GetMapping("/mono")
    public Mono<String> getMono() {
        return Mono.just(UUID.randomUUID().toString());
    }

    @GetMapping("/flux")
    public Flux<String> getFlux() {
        return Flux.just(1, 10).map(SimonUtil::format);
    }

    /**
     * SSE text/event-stream 服务端推送
     * @return
     */
    @GetMapping(value = "/flux/sse",
            produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> getFluxSSE() {
        return Flux.just(1, 10)
                .delayElements(Duration.ofMillis(500))
                .map(SimonUtil::format)
                .log();
    }

    /**
     * interval text/event-stream 服务端推送
     * @return
     */
    @GetMapping(value = "/flux/interval",
            produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> getFluxInterval() {
        return Flux.interval(Duration.ofMillis(500))
                .doOnNext(count -> {
                    if (count == 10) {
                        throw new BusinessException("我想停掉");
                    }
                })
                .onErrorComplete()
                .map(count -> ServerSentEvent.builder(SimonUtil.format(count + 1))
                        .id(String.valueOf(count + 1))
                        .comment("c-" + count)
                        .event("e-" + count)
                        .build())
                .log();
    }


}
